package org.util.common;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by Sinceow on 14-3-13.
 */
public class SortUtil {


    public static void sortByFieldAsc(List<?> objects, Class<?> clazz, String fieldName) throws NoSuchFieldException {
        if(objects == null || objects.size() == 0){
            return;
        }
        Field field = clazz.getDeclaredField(fieldName);
        Collections.sort(objects, new SelfComparator(clazz, field, SelfComparator.ASC));
    }

    public static void sortByFieldDesc(List<?> objects, Class<?> clazz, String fieldName) throws NoSuchFieldException {
        if(objects == null || objects.size() == 0){
            return;
        }
        Field field = clazz.getDeclaredField(fieldName);
        Collections.sort(objects, new SelfComparator(clazz, field, SelfComparator.DESC));
    }


    private static class SelfComparator implements Comparator<Object>{

        public static final int ASC = 1;
        public static final int DESC = -1;
        private Class<?> clazz;
        private Field field;
        private int sortType;


        public SelfComparator(Class<?> clazz, Field field, int sortType){
            this.clazz = clazz;
            this.field = field;
            this.sortType = sortType;
        };

        @Override
        public int compare(Object o1, Object o2) {
            Method[] methods = this.clazz.getMethods();
            String methodName = "get" + this.field.getName();
            for(Method method: methods){
                if(methodName.equalsIgnoreCase(method.getName())){
                    try {
                        Object value1 = method.invoke(o1);
                        Object value2 = method.invoke(o2);
                        if(value1 instanceof Integer && value2 instanceof Integer){
                            Integer i1 = (Integer)value1;
                            Integer i2 = (Integer)value2;
                            return  i1.compareTo(i2) * this.sortType;
                        }else if(value1 instanceof Long && value2 instanceof Long){
                            Long i1 = (Long)value1;
                            Long i2 = (Long)value2;
                            return i1.compareTo(i2) * this.sortType;
                        }else if(value1 instanceof Double && value2 instanceof Double){
                            Double i1 = (Double)value1;
                            Double i2 = (Double)value2;
                            return i1.compareTo(i2) * this.sortType;
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
            return 0;
        }
    }
}
